/**
 * HTTP请求封装
 * 基于uni.request封装，支持请求拦截、响应拦截、错误处理等
 */

import { currentConfig } from '@/config/app-config.js'

// 基础配置
const config = {
  baseURL: currentConfig.baseURL,
  timeout: currentConfig.timeout,
  enableLog: currentConfig.enableLog,
  header: {
    'Content-Type': 'application/json;charset=UTF-8'
  }
}

// 存储token
let token = ''

/**
 * 获取token
 */
const getToken = () => {
  if (!token) {
    token = uni.getStorageSync('token') || ''
  }
  return token
}

/**
 * 设置token
 */
const setToken = (newToken) => {
  token = newToken
  uni.setStorageSync('token', newToken)
}

/**
 * 清除token
 */
const clearToken = () => {
  token = ''
  uni.removeStorageSync('token')
}

/**
 * 请求拦截器
 */
const requestInterceptor = (options) => {
  // 添加token到请求头
  const token = getToken()
  if (token) {
    options.header.Authorization = `${token}`
  }

  // 添加请求ID用于追踪
  options.header['X-Request-ID'] = generateRequestId()

  if (config.enableLog) {
    console.log('🚀 Request:', {
      url: options.url,
      method: options.method,
      data: options.data,
      header: options.header
    })
  }

  return options
}

/**
 * 响应拦截器
 */
const responseInterceptor = (response) => {
  const { statusCode, data } = response

  if (config.enableLog) {
    console.log('📦 Response:', {
      url: response.config?.url,
      statusCode,
      data,
      dataType: typeof data
    })
  }

  // HTTP状态码处理
  if (statusCode === 200) {
    // 更宽松的业务状态码处理
    if (data.code === 0 || data.code === 200 || data.success === true || data.status === 'success') {
      console.log('✅ 业务请求成功')
      return data
    } else {
      // 业务错误，记录详细信息但不立即显示错误
      if (config.enableLog) {
        console.error('❌ 业务错误:', {
          code: data.code,
          message: data.message || data.msg || data.error,
          data: data
        })
      }
      handleError(data)
      return Promise.reject(data)
    }
  } else if (statusCode === 401) {
    // 未授权，清除token并跳转登录
    clearToken()
    uni.reLaunch({
      url: '/pages/login'
    })
    return Promise.reject(new Error('登录已过期，请重新登录'))
  } else if (statusCode === 403) {
    uni.showToast({
      title: '无权限访问',
      icon: 'none'
    })
    return Promise.reject(new Error('无权限访问'))
  } else if (statusCode >= 500) {
    uni.showToast({
      title: '服务器错误',
      icon: 'none'
    })
    return Promise.reject(new Error('服务器错误'))
  } else {
    uni.showToast({
      title: `请求失败 ${statusCode}`,
      icon: 'none'
    })
    return Promise.reject(new Error(`请求失败 ${statusCode}`))
  }
}

/**
 * 错误处理
 */
const handleError = (error) => {
  if (config.enableLog) {
    console.error('🚨 请求错误详情:', error)
  }

  // 尝试从不同字段获取错误信息
  const message = error.message || error.msg || error.error || error.info || '请求失败'

  if (config.enableLog) {
    console.log('💬 显示错误信息:', message)
  }

  uni.showToast({
    title: message,
    icon: 'none',
    duration: 3000
  })
}

/**
 * 生成请求ID
 */
const generateRequestId = () => {
  return Date.now().toString(36) + Math.random().toString(36).substr(2)
}

/**
 * 基础请求方法
 */
const request = (options) => {
  return new Promise((resolve, reject) => {
    // 请求拦截
    options = requestInterceptor({
      url: config.baseURL + options.url,
      method: options.method || 'GET',
      data: options.data || {},
      header: {
        ...config.header,
        ...options.header
      },
      timeout: options.timeout || config.timeout
    })

    uni.request({
      ...options,
      success: (response) => {
        response.config = options
        try {
          const result = responseInterceptor(response)
          resolve(result)
        } catch (error) {
          reject(error)
        }
      },
      fail: (error) => {
        if (config.enableLog) {
          console.error('❌ Request Failed:', error)
          console.error('❌ 错误详情:', {
            errMsg: error.errMsg,
            errCode: error.errCode,
            data: error.data,
            statusCode: error.statusCode
          })
        }

        let message = '网络请求失败'
        if (error.errMsg) {
          if (error.errMsg.includes('timeout')) {
            message = '请求超时'
          } else if (error.errMsg.includes('fail') || error.errMsg.includes('fail')) {
            message = '网络连接失败'
          } else if (error.errMsg.includes('ssl') || error.errMsg.includes('certificate')) {
            message = 'SSL证书错误'
          } else if (error.errMsg.includes('CORS')) {
            message = '跨域请求被阻止'
          } else {
            message = error.errMsg
          }
        }

        uni.showToast({
          title: message,
          icon: 'none',
          duration: 4000
        })

        reject(error)
      }
    })
  })
}

/**
 * GET请求
 */
const get = (url, params = {}, options = {}) => {
  return request({
    url,
    method: 'GET',
    data: params,
    ...options
  })
}

/**
 * POST请求
 */
const post = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'POST',
    data,
    ...options,
		header: {
			'Content-Type': 'application/x-www-form-urlencoded'
		}
  })
}
/**
 * POST请求
 */
const postJSON = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'POST',
    data,
    ...options,
		header: {
			'Content-Type': 'application/json'
		}
  })
}

/**
 * PUT请求
 */
const put = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'PUT',
    data,
    ...options
  })
}

/**
 * DELETE请求
 */
const del = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'DELETE',
    data,
    ...options
  })
}

/**
 * 文件上传
 */
const upload = (url, filePath, formData = {}, options = {}) => {
  return new Promise((resolve, reject) => {
    const token = getToken()

    uni.uploadFile({
      url: config.baseURL + url,
      filePath,
      name: options.name || 'file',
      formData,
      header: {
        Authorization: token ? `Bearer ${token}` : '',
        ...options.header
      },
      success: (response) => {
        try {
          const data = JSON.parse(response.data)
          if (data.code === 0 || data.success) {
            resolve(data)
          } else {
            handleError(data)
            reject(data)
          }
        } catch (error) {
          reject(new Error('上传响应解析失败'))
        }
      },
      fail: (error) => {
        uni.showToast({
          title: '上传失败',
          icon: 'none'
        })
        reject(error)
      }
    })
  })
}

export default {
  request,
  get,
  post,
	postJSON,
  put,
  del,
  upload,
  setToken,
  clearToken,
  getToken,
  config
}